<template>
	<view id="drag-view" class="drag-container" :class="{ transition: autoDocking && !moving }" :style="{
      right: `${right}px`,
      top: `${top}`,
      width: `${size}rpx`,
      height: `${size}rpx`,
      zIndex: zIndex,
    }" @touchend="touchend" @touchmove.stop.prevent="touchmove">
		<slot />
	</view>
</template>

<script>
	export default {
		name: 'Dragview',
		props: {
			/**
			 * 按钮大小
			 */
			cTop: {
				type: [Number, String],
				default: 500,
			},
			/**
			 * 按钮大小
			 */
			size: {
				type: Number,
				default: 200,
			},
			/**
			 * 层级
			 */
			zIndex: {
				type: Number,
				default: 999,
			},
			/**
			 * x轴边界限制
			 */
			xEdge: {
				type: Number,
				default: 0,
			},
			/**
			 * y轴边界限制
			 */
			yEdge: {
				type: Number,
				default: 50,
			},
			/**
			 * 自动停靠
			 */
			autoDocking: {
				type: Boolean,
				default: true,
			},
		},
		data() {
			return {
				cShow: true,
				top: '500px',
				right: 20,
				width: 0,
				height: 0,
				moving: true,
			}
		},
		watch: {
			cTop(val) {
				this.comPos(val)
			},
		},
		created() {
			this.comPos()
		},
		mounted() {
			this.init()
		},
		methods: {
			comPos(val) {
				if (val) {
					this.top = typeof val === 'string' ? val : `${val}px`
				} else {
					this.top = typeof this.cTop === 'string' ? this.cTop : `${this.cTop}px`
				}
			},
			init() {
				// 获取窗口尺寸
				const {
					windowWidth,
					windowHeight,
					windowTop
				} = uni.getSystemInfoSync()
				this._windowWidth = windowWidth
				this._windowHeight = windowHeight
				if (windowTop) {
					this._windowHeight += windowTop
				}

				// 计算按钮初始位置
				const query = uni.createSelectorQuery().in(this)
				query
					.select('#drag-view')
					.boundingClientRect((data) => {
						if (!data) return
						const {
							width,
							height
						} = data
						this.width = width
						this.height = height
						this._offsetWidth = width / 2
						this._offsetHeight = height / 2
						this.left = this._windowWidth - this.width - this.xEdge
						this.top = `${this._windowHeight - this.height - this.yEdge}px`
						this.comPos()
					})
					.exec()
			},

			// 拖动
			touchmove({
				touches
			}) {
				if (touches.length !== 1) return false

				this.moving = true
				const {
					clientX,
					clientY
				} = touches[0]
				this.left = clientX - this._offsetWidth

				let _clientY = clientY - this._offsetHeight
				// #ifdef H5
				_clientY += this.height
				// #endif
				this.top = `${_clientY}px`
			},

			// 松手
			touchend() {
				// 左右边界，松手自动停靠
				if (this.autoDocking) {
					const rigthEdge = this._windowWidth - this.width - this.xEdge
					if (this.left < this._windowWidth / 2 - this._offsetWidth) {
						this.left = this.xEdge
					} else {
						this.left = rigthEdge
					}
				}

				// 上下边界
				const bottomEdge = this._windowHeight - this.height - this.yEdge
				if (this.top < 50) {
					this.top = `${50}px`
				} else if (this.top > bottomEdge) {
					this.top = `${bottomEdge}px`
				}

				this.moving = false
			},
		},
	}
</script>

<style lang="scss" scoped>
	.drag-container {
		display: flex;
		justify-content: center;
		align-items: center;
		border-radius: 50%;
		position: fixed;

		&.transition {
			transition: all 0.3s ease;
		}
	}
</style>